package com.abel.bigwater.dataserver.model.ewide

import com.abel.bigwater.data.BcdString
import io.netty.buffer.ByteBuf
import org.joda.time.DateTime
import java.util.*

abstract class TermData(val type: KmingDataType, val pduLen: Int = -1) {

    /**
     * the data length includes data-type byte.
     */
    abstract fun bufLength(): Int

    abstract fun parseBuf(buf: ByteBuf): Boolean

    abstract fun pack(buf: ByteBuf)

    companion object {
        fun peekType(buf: ByteBuf) = if (buf.readableBytes() < 1) null else
            KmingDataType.findByCode(buf.duplicate().readUnsignedByte())

        fun fromFullTime(time: Date): BcdString {
            val dt = DateTime(time)
            return BcdString(byteArrayOf(dt.year.rem(100).toByte(), dt.monthOfYear.toByte(), dt.dayOfMonth.toByte(),
                    dt.hourOfDay.toByte(), dt.minuteOfHour.toByte(), dt.secondOfMinute.toByte()), true)
        }

        fun BcdString.toFullTime(): Date {
            assert(6 == size)

            return DateTime(DateTime.now().year.div(100) * 100 + bcdArray!![0].toInt(),
                    bcdArray!![1].toInt(), bcdArray!![2].toInt(),
                    bcdArray!![3].toInt(), bcdArray!![4].toInt(),
                    bcdArray!![5].toInt()).toDate()
        }

        fun fromFullYearTime(time: Date): BcdString {
            val dt = DateTime(time)
            return BcdString(byteArrayOf(dt.year.div(100).toByte(), dt.year.rem(100).toByte(),
                    dt.monthOfYear.toByte(), dt.dayOfMonth.toByte(),
                    dt.hourOfDay.toByte(), dt.minuteOfHour.toByte(), dt.secondOfMinute.toByte()), true)
        }

        fun BcdString.toFullYearTime(): Date {
            assert(7 == size)

            return DateTime(bcdArray!![0].toInt() * 100 + bcdArray!![1].toInt(),
                    bcdArray!![2].toInt(), bcdArray!![3].toInt(),
                    bcdArray!![4].toInt(), bcdArray!![5].toInt(),
                    bcdArray!![6].toInt()).toDate()
        }
    }
}